﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


/*
 * Check http://www.youtube.com/watch?v=2wgeDQlwnQ0 for precise explanation
 * */
public class SelectionQuad : MonoBehaviour 
{
	public static Rect selectionRect = new Rect(0,0,0,0); //
	public Texture2D textureSelectionQuad = null;
	public static List<GameObject> UnitsSelected = new List<GameObject>();

	private Vector3 posStartClick = -Vector3.one; 


	

	// Update is called once per frame
	void Update () 
	{
		DrawQuad ();
		ApplyOrder ();
	}


	void ApplyOrder() 
	{
		if (Input.GetMouseButtonDown (1)) 
		{
			if (UnitsSelected.Count != 0) 
			{
				RaycastHit[] hits;
				Ray rayonPointeur = Camera.main.ScreenPointToRay(Input.mousePosition);
                hits = Physics.RaycastAll(rayonPointeur).OrderBy(h => h.distance).ToArray(); // SO MUCH OP. Order collider using their distance.

				foreach (RaycastHit hit in hits)
				{
					if (hit.collider.tag == ListTags.tagClouds)
					{
                        DefineDestination(UnitsSelected, hit.point, ListTags.tagClouds);
                        break;
					}
                    else if (hit.collider.tag == ListTags.tagRessource)
                    {
                        DefineDestination(UnitsSelected, hit.point, ListTags.tagRessource);
                        break;
                    }
                    else if (hit.collider.tag == ListTags.tagTotem)
                    {
                        if (hit.collider.networkView.isMine) 
                        {
                            DefineDestination(UnitsSelected, hit.point, ListTags.tagTotem);
                        }
                        else
                        {
                            DefineDestination(UnitsSelected, hit.point, ListTags.tagUnits); //If it's not our Totem, consider it as a simple unit.
                            foreach (GameObject unit in UnitsSelected)
                            {
                                unit.GetComponent<BehaviorUnits>().SetEnemy(hit.collider.gameObject);
                            }
                        }
                        break;
                    }
                    else if (hit.collider.tag == ListTags.tagUnits)
                    {
                        if (!hit.collider.networkView.isMine)
                        {
                            DefineDestination(UnitsSelected, hit.point, ListTags.tagUnits);
                            foreach (GameObject unit in UnitsSelected)
                            {
                                unit.GetComponent<BehaviorUnits>().SetEnemy(hit.collider.gameObject);
                            }
                        }
                        else
                        {
                            DefineDestination(UnitsSelected, hit.point, ListTags.tagClouds); //Make units follow?
                        }
                        
                        break;
                    }
				}

			}	
		}

	}

	void DefineDestination(List<GameObject> units, Vector3 destination, string tagClick = "")
	{
        /*
         * Optimisation --.
         * */
		units[0].GetComponent<NavMeshAgent>().SetDestination(destination);
		float diametre = 0f; //En fait, c'est le rayon, mais osef

		foreach (GameObject unit in units)
		{
			diametre += unit.GetComponent<NavMeshAgent>().radius;
		}

        diametre = Mathf.Sqrt((4f * diametre) / Mathf.PI); // L'on prévoit 4 fois la surface necessaire pour le placement des unités. Il suffit de changer le chiffre "4" pour plus ou moins de distance entre les unités
		foreach (GameObject unit in units)
		{
			unit.GetComponent<BehaviorUnits>().SetDestination
                (new Vector3(Random.Range(destination.x - diametre, destination.x + diametre), destination.y, Random.Range(destination.z - diametre, destination.z + diametre)), tagClick);
		}
        units[0].GetComponent<BehaviorUnits>().SetDestination(destination, tagClick);

	}

	void DrawQuad ()
	{
		if (posStartClick != -Vector3.one)
		{
			if (selectionRect.width < 0)
			{
				selectionRect.x += selectionRect.width;
				selectionRect.width = - selectionRect.width;
			}
			if (selectionRect.height < 0)
			{
				selectionRect.y += selectionRect.height;
				selectionRect.height = -selectionRect.height;
			}
		}

		if (Input.GetMouseButtonDown (0)) 
		{
			posStartClick = Input.mousePosition;
		}
		else if (Input.GetMouseButtonUp(0))
		{
			if (selectionRect.width < 0)
			{
				selectionRect.x += selectionRect.width;
				selectionRect.width = - selectionRect.width;
			}
			if (selectionRect.height < 0)
			{
				selectionRect.y += selectionRect.height;
				selectionRect.height = -selectionRect.height;
			}
			posStartClick = -Vector3.one; 
		}

		if (Input.GetMouseButton(0)) 
		{
			selectionRect = new Rect(posStartClick.x,InverseYForScreen(posStartClick.y), Input.mousePosition.x - posStartClick.x,InverseYForScreen(Input.mousePosition.y) - InverseYForScreen(posStartClick.y));
		}
	}

	void OnGUI() //Actual drawing
	{
		if (posStartClick != -Vector3.one)
		{
			GUI.color = new Color(1,1,1,0.5f);
			GUI.DrawTexture(selectionRect, textureSelectionQuad);

		}
	}

	public static float InverseYForScreen(float toInverse)
	{
		return Screen.height - toInverse;
	}
}
